import { ConnectableObservable, fromEvent, Observable } from "rxjs";
import { shareReplay, switchMap, publish, publishLast, share } from "rxjs/operators";
import { getLogger } from "../utils";

const log = getLogger("Purpose");
log("Ajax request with caching eager");

const btn = document.createElement("button");
btn.innerText = "Click me";
document.body.appendChild(btn);

interface TODO {
    userId: number;
    id: number;
    title: string;
    completed: boolean;
}

function fetchTodos(id: number) {
    // [es6 promise - How to convert a Fetch API response to RxJS Observable ? - Stack Overflow](https://stackoverflow.com/questions/44877062/how-to-convert-a-fetch-api-response-to-rxjs-observable )
    return new Observable<TODO>(observer => {
        console.log("%cFetching TODO from server at: " + new Date().getTime(), "color:magenta;");
        fetch('https://jsonplaceholder.typicode.com/todos/' + id)
            .then(response => response.json())
            .then((data: TODO) => {
                if (!data || typeof data.title !== "string") throw new Error("invalid todo");
                observer.next(data);
                observer.complete();
            })
            .catch(err => observer.error(err));
    });
}

const fetchedOnceAndCachedEager = fetchTodos(1).pipe(shareReplay(1));
const sub = fetchedOnceAndCachedEager.subscribe(() => sub.unsubscribe());

fromEvent(btn, "click").pipe(switchMap(() => fetchedOnceAndCachedEager)).subscribe(res => {
    log(`Fetched todo: ${JSON.stringify(res)} at ${new Date().getTime()}`);
});